#ifndef MODULE_H
#define MODULE_H
#include "noncopyable.h"
#include "EventLoop.h"
#include "Channel.h"
#include "Logger.h"
#include "Common.h"
class Module : noncopyable
{

public:
    Module() { module_init(); }
    Module(int fd) : m_fd(fd) { module_init(); }
    void module_init()
    {
        m_loop = EventLoop::getInstance();
        m_woker_pool=ThreadPool::getInstance();
        m_channel = std::make_shared<Channel>(m_fd);
        auto handle_back = std::bind(&Module::handle_event, this, std::placeholders::_1);
        m_channel->setHandleCallback(handle_back);
    }
    ~Module()
    {
        disable();
    };
    virtual void read_message()
    {
        uint8_t temp_buffer[1024] = {0};
        int len = read(m_channel->getfd(), temp_buffer, 1024);
        m_read_buffer.write(temp_buffer, len);
        if (readCallback_)
        {
            if (threadProc)
            {
                m_woker_pool->addTask(Task(readCallback_,&m_read_buffer));
            }
            else{
                readCallback_(&m_read_buffer);
            }
            
            
        }
    }
    virtual void write_message()
    {
    }
    virtual void close_conn()
    {
        if (closeCallback_)
        {
            closeCallback_(m_channel.get()); // Call close callback
        }
        disable();
    }
    int handle_event(void *arg)
    {
        epoll_event *event = static_cast<epoll_event *>(arg);
        LOG_INFO("m_channel->revent=%d\n", event->events);
        if (event->events & (EPOLLIN | EPOLLPRI))
        {
            read_message();
        }
        if (event->events & EPOLLERR || event->events & EPOLLHUP)
        {
           close_conn();
        }

        return 1;
    }
    // user callback
    void set_read_callback(callback cb) { readCallback_ = cb; }
    void set_close_callback(callback cb) { closeCallback_ = cb; }
    void set_error_callback(callback cb) { errorCallback_ = cb; }
    // open or close read
    void open_read()
    {
        m_channel->enableReading();
        if (m_channel->isReading())
        {
            m_loop->update_event(EPOLL_CTL_ADD, m_channel.get());
        }
    };
    void close_read()
    {
        m_loop->update_event(EPOLL_CTL_MOD, m_channel.get());
        m_channel->disableReading();
    };
    void disable()
    {
        // 关闭套接字
        if (m_fd != -1)
        {
            m_channel->disableAll();
            m_loop->update_event(EPOLL_CTL_DEL, m_channel.get());
            close(m_fd);
        }
    }
    int get_fd() const { return m_fd; }
    void enableThreadProc() { threadProc = true; }
    void disableThreadProc() { threadProc= false; }
    // void set_write_callback(callback cb) { writeCallback_ = std::move(cb); }
protected:
    EventLoop::ptr m_loop;
    ThreadPool::ptr m_woker_pool;
    Channel::ptr m_channel;
    int m_fd = -1;
    bool threadProc = true;
    callback readCallback_;
    callback closeCallback_;
    callback errorCallback_;
    Buffer m_read_buffer;
};
#endif